package org.example.innovate.util;

import com.aliyun.oss.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.example.innovate.common.CommonResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.HandlerMethodValidationException;

import javax.validation.ConstraintViolationException;

/*
@RestControllerAdvice 是 Spring Framework 提供的注解，用于定义全局异常处理类，并且结合 @ExceptionHandler 注解来处理异常。
与 @ControllerAdvice 不同的是，@RestControllerAdvice 默认情况下会将返回值转换为 JSON 格式。
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /*
    @ResponseStatus(HttpStatus.BAD_REQUEST) 是一个注解，用于在异常处理方法上指定特定的HTTP状态码。当该异常被抛出时，将返回指定的HTTP状态码给客户端。
    @ExceptionHandler(...) 是一个异常处理注解，用于捕获请求的异常。当客户端发送的请求消息无法被框架正确解析时，将抛出该异常并调用对应的异常处理方法。
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public CommonResponse<Object> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        //打印异常
        logger.error("异常 '{}',类 '{}'", e.getMessage(), e.getClass());
        //返回前端
        return CommonResponse.createForError("缺少参数");
    }

    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public CommonResponse<Object> handleConstraintViolationException(ConstraintViolationException e) {
        logger.error("异常 '{}',类 '{}'", e.getMessage(), e.getClass());
        return CommonResponse.createForError(e.getMessage());
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public CommonResponse<Object> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        logger.error("异常 '{}',类 '{}'", e.getMessage(), e.getClass());
        return CommonResponse.createForError("数据格式错误");
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public CommonResponse<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        logger.error("异常 '{}',类 '{}'", e.getMessage(), e.getClass());
        return CommonResponse.createForError("数据不完整");
    }

    @ExceptionHandler(HandlerMethodValidationException.class)
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public CommonResponse<Object> handleHandlerMethodValidationException(HandlerMethodValidationException e) {
        logger.error("异常 '{}',类 '{}'", e.getMessage(), e.getClass());
        return CommonResponse.createForError("数据有误");
    }

    //没有token
    @ExceptionHandler(ServiceException.class)
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public CommonResponse<Object> handleHandlerServiceException(ServiceException e) {
        logger.error("异常 '{}',类 '{}'", e.getMessage(), e.getClass());
        return CommonResponse.createForError(e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public CommonResponse<Object> handleException(Exception e) {
        logger.error("异常 '{}',类 '{}'", e.getMessage(), e.getClass());
        return CommonResponse.createForError("服务器错误");
    }


}
